using System;
using System.Collections.Generic;
using System.Text;
using MacomberMap.Common.Database_Interface;
using System.DirectoryServices;
using MacomberMap.Common.Types;
using System.Xml;

namespace MacomberMap.Common.Permissions
{
    /// <summary>
    /// This class holds the information on the current user, including role, information, accessible databases and permissions
    /// </summary>
    public static class MM_User
    {
        #region Variable declarations
        /// <summary>Whether ownership information should be shown</summary>
        public static bool ShowOwnership = true;

        /// <summary>Whether DUNS information should be shown</summary>
        public static bool ShowDUNS = true;

        /// <summary>Whether the user can switch different models</summary>
        public static bool AllowModelSwitching = true;

        /// <summary>Whether telephone information should be shown</summary>
        public static bool ShowTelephone = true;

        /// <summary>Whether Processes should be shown</summary>
        public static bool ShowProcesses = true;

        /// <summary>Whether views should be shown</summary>
        public static bool ShowViews = true;

        /// <summary>Whether units are shown (right-click menu or search)</summary>
        public static bool ShowUnits = true;

        /// <summary>Whether loads are shown (right-click menu or search)</summary>
        public static bool ShowLoads = true;

        /// <summary>Whether shunt compensators are shown (right-click menu or search)</summary>
        public static bool ShowShuntCompensators = true;

        /// <summary>Whether transformers are shown (right-click menu or search)</summary>
        public static bool ShowTransformers = true;

        /// <summary>Whether buses are shown (right-click menu or search)</summary>
        public static bool ShowBuses = true;

        /// <summary>Whether estimated MVAs are displayed (on network map, or right-click menu)</summary>
        public static bool ShowEstMVAs = true;

        /// <summary>Whether estimated voltages and pUs are displayed (on network map, or right-click menu)</summary>
        public static bool ShowEstVs = true;

        /// <summary>Whether telemetered voltages and pUs are displayed (on network map, or right-click menu)</summary>
        public static bool ShowTelVs = true;

        /// <summary>Whether telemetered MVAs are displayed (on network map, or right-click menu)</summary>
        public static bool ShowTelMVAs = true;

        /// <summary>Whether estimated MVARs are displayed (on network map, or right-click menu)</summary>
        public static bool ShowEstMVARs = true;

        /// <summary>Whether telemetered MVARs are displayed (on network map, or right-click menu)</summary>
        public static bool ShowTelMVARs = true;

        /// <summary>Whether estimated MWs are displayed (on network map, or right-click menu)</summary>
        public static bool ShowEstMWs = true;

        /// <summary>Whether telemetered MWs are displayed (on network map, or right-click menu)</summary>
        public static bool ShowTelMWs = true;

        /// <summary>Whether limits are displayed (on network map, or right-click menu)</summary>
        public static bool ShowLimits = true;

        /// <summary>Whether loading percentages (MVA/Normal limit) are displayed (on network map, or right-click menu)</summary>
        public static bool ShowPercentageLoading = true;

        /// <summary>Whether the user  call up one-lines</summary>
        public static bool ShowOneLines = true;

        /// <summary>Whether the user can move the map around elements</summary>
        public static bool ShowMoveMap = true;

        /// <summary>Whether the user  Show notes</summary>
        public static bool ShowNotes = true;

        /// <summary>Whether the user can call up the property page</summary>
        public static bool ShowPropertyPage = false;

        /// <summary>Whether the user  Show Events</summary>
        public static bool ShowEvents = true;

        /// <summary>Whether the user  Show the list of elements within a substation</summary>
        public static bool ShowElementTypes = true;

        /// <summary>Whether the user  Show the list of KV Levels within a substation</summary>
        public static bool ShowKVLevels = true;

        /// <summary>Whether the user can see a line's distance</summary>
        public static bool ShowDistance = true;

        /// <summary>Whether counties are shown on substation displays</summary>
        public static bool ShowCounties = true;

        /// <summary>Whether the website option is shown on substation displays</summary>
        public static bool ShowWebsite = false;

        /// <summary>Whether TEIDs are shown</summary>
        public static bool ShowTEIDs = true;

        /// <summary>Whether the user  create notes</summary>
        public static bool CreateNotes = true;

        /// <summary>Whether the search feature is available to the user</summary>
        public static bool SearchAvailable = true;

        /// <summary>Whether the user  draw a standard lasso</summary>
        public static bool LassoStandard = true;

        /// <summary>Whether the user  create an lasso including invisible elements</summary>
        public static bool LassoInvisible = true;

        /// <summary>Whether the user  Show EMS ICCP/ISD links</summary>
        public static bool DisplayICCPISDLinks = true;

        /// <summary>Whether the user  Show the communications status between MM and connected systems</summary>
        public static bool DisplayMMCommLinks = true;

        /// <summary>Whether the user  Show energized lines</summary>
        public static bool ShowEnergizedLines = true;

        /// <summary>Whether the user  Show de-energized lines</summary>
        public static bool ShowDeenergizedLines = true;

        /// <summary>Whether the user  Show partially energized lines</summary>
        public static bool ShowPartiallyEnergizedLines = true;

        /// <summary>How far back the user  go in history</summary>
        public static TimeSpan HistoricalTime = TimeSpan.FromSeconds(0);

        /// <summary>How far into the future the user  go</summary>
        public static TimeSpan FutureTime = TimeSpan.FromSeconds(0);

        /// <summary>Whether boilerplate text needs to be added</summary>
        public static string BoilerplateText = "";

        /// <summary>Whether the user's activity should be logged</summary>
        public static bool LogActivity = false;

        /// <summary>Whether the unit's generation type is shown</summary>
        public static bool ShowUnitGenerationType = true;

        /// <summary>Whether the default connectors should be used</summary>
        public static bool DefaultConnectors = false;

        /// <summary>Whether the user can create a savecase</summary>
        public static bool CreateSavecase = true;

        /// <summary>Whether the user can access the display properties page</summary>
        public static bool DisplayProperties = true;

        /// <summary>The maximum zoom level for the network map</summary>
        public static int MaxZoom = 30;

        /// <summary>The miniumum zoom level for the network map.</summary>
        public static int MinZoom = 5;

        /// <summary>Whether the user can edit substation locations</summary>
        public static bool EditSubstationLocations;

        /// <summary>The default view for the user</summary>
        public static MM_View DefaultView;

        /// <summary>The ID for the current role</summary>
        public static int RoleID;

        #endregion

        #region User login

        /// <summary>
        /// Attempt to log in to the MM system with the existing credentials. If succesful, apply our views and permissions
        /// </summary>
        /// <param name="DbConnection"></param>
        /// <returns></returns>
        public static bool LoginCurrentUser(MM_Database DbConnection)
        {
            int UserRole;
            if ((UserRole = DbConnection.LookupUser(Environment.UserName.ToUpper())) != -1)
            {
                ActivateRole(UserRole, DbConnection);                
                return true;
            }
            else
                return false;
        }


        /// <summary>
        /// Attempt to log in to the MM system with a specified username and password. If succesful, apply our views and permissions
        /// </summary>
        /// <param name="UserName">The user name</param>
        /// <param name="Password">The password</param>
        /// <param name="DbConnection">The MM database containing authorized users</param>
        /// <returns></returns>
        public static bool LoginUser(String UserName, String Password, MM_Database DbConnection)
        {
            int UserRole;
            if ((UserRole = DbConnection.LookupUser(UserName)) != -1 && AuthenticateUser(UserName, Password))
            {
                ActivateRole(UserRole, DbConnection);
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// Load all information for the specified role, and activate it
        /// </summary>
        /// <param name="UserRole">The role assigned to the authenticated user</param>
        /// <param name="DbConnection">The Oracle database connection</param>
        private static void ActivateRole(int UserRole, MM_Database DbConnection)
        {
            MM_User.RoleID = UserRole;

            //Retrieve our display and permissions XML.
            String PermissionsXML;
            int DefaultView;
            DbConnection.LoadRole(UserRole, out DefaultView, out PermissionsXML);



            //Load our KV levels, element types, and Event types         
            DbConnection.LoadViews(UserRole, DefaultView);

            //Apply permissions
            XmlDocument inDoc = new XmlDocument();
            inDoc.LoadXml(PermissionsXML);
            try
            {
                MM_Serializable.ReadXml(inDoc.DocumentElement, typeof(MM_User));
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error reading and processing XML: " + ex.Message);
            }
        }

        /// <summary>
        /// Authenticate a user using active directory
        /// </summary>
        /// <param name="Username">The username to check</param>
        /// <param name="Password">The password to check</param>
        /// <returns></returns>
        private static bool AuthenticateUser(String Username, String Password)
        {
            bool authenticated = false;
            try
            {
                DirectoryEntry dirEntry = new DirectoryEntry("LDAP://ERCOT", Username, Password);
                dirEntry.AuthenticationType = AuthenticationTypes.Secure;                
                object nativeObject = dirEntry.NativeObject;
                authenticated = true;
            }
            catch (Exception)
            { }
            return authenticated;
        }
        #endregion
    }
}
